package com.sec.etech.nc.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.aspose.pdf.Page;
import com.aspose.words.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sec.etech.common.constant.DBConstant;
import com.sec.etech.common.service.Mail;
import com.sec.etech.common.util.DataTable;
import com.sec.etech.common.util.DataTableUtil;
import com.sec.etech.common.util.RequestHolder;
import com.sec.etech.file.service.EtechFileHandlerService;
import com.sec.etech.file.service.EtechFileService;
import com.sec.etech.nc.mapper.NcMapper;
import com.sec.etech.nc.model.Nc;
import com.sec.etech.nc.model.NcFiles;
import com.sec.etech.org.service.EtechUserService;
import lombok.SneakyThrows;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.base.api.exception.BusinessMessage;
import org.openbpm.base.api.response.impl.ResultMsg;
import org.openbpm.sys.api.service.ISysDataSourceService;
import org.openbpm.sys.util.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@lombok.extern.slf4j.Slf4j
@Service
public class NcService extends ServiceImpl<NcMapper, Nc> {

    @Resource
    private EtechFileHandlerService fileHandlerService;
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ISysDataSourceService sysDataSourceService;
    @Resource
    NcFilesService ncFileService;
    @Resource
    NcHelper ncHelper;
    @Resource
    EtechUserService etechUserService;
    @Resource
    EtechFileService etechFileService;

    public Nc getNc(Long ncid) {
        // 需要先建立视图proc_ncs， 建视图语句 ../sql/view.sql
        String str = "SELECT a.ncid,a.statusid,a.verify,a.versions,a.ncnum,a.ncplanid,a.demanderuid,a.route_step_id as routeStepId,a.partsid," +
                "if(a.partsid>0,t6.partsnum,if(a.partsnum is not null and a.partsnum!='',a.partsnum,a.componentnum)) partsnum," +
                "if(a.partsid>0,t6.partsname,if(a.partsname is not null and a.partsname!='',a.partsname,a.componentname)) partsname," +
                "d.username AS demanderuname,d.tel AS demanderutel,a.demanddprtid,e.dprtname AS demanddprtname,a.mainclassid,a.mainclassname," +
                "a.processid,a.processnum,a.processname,a.componentid,a.componentnum,a.componentname,a.projectid," +
                "a.manufactureorder,a.projectname,a.turningdate,a.workblankdate," +
                "a.serial_num,a.operationid,a.is_biaxial," +
                "IF(a.route_step_id > 0,m.op_no,'') opNo," +
                "IF(a.route_step_id > 0,m.operationname,a.operationname) operationname," +
                "a.workshopid,a.workshopname,a.machineid,a.machinenum,a.machinecode,a.plandate,a.finishdate,a.workday,a.checkworkday," +
                "CONCAT(a.machinename,(IF(length(a.machinenvulgo)>0,CONCAT('(', a.machinenvulgo, ')' ), '' ))) AS machinenames," +
                "CONCAT(a.machinecode,' ',a.machinename) AS machinename," +
                "a.designeruid,f.username AS designeruname," +
                "a.checkeruid,g.username AS checkeruname," +
                "a.revieweruid,h.username AS revieweruname," +
                "a.approveruid,j.username AS approveruname," +
                "a.tips,a.commonncid,i.ncnum AS commonncnum," +
                "a.abandontips,a.signin,a.signeruid,k.username AS signeruname,a.signdate,a.subfield," +
                "a.postuid,b.username AS postuser,a.postdate,a.lastuid,c.username AS lastuser,a.lastdate " +
                "FROM proc_ncs AS a " +
                "left join wss_user AS b on a.postuid = b.uid " +
                "left join wss_user AS c on a.lastuid = c.uid " +
                "left join wss_user AS d on a.demanderuid = d.uid " +
                "left join wss_dprt AS e on a.demanddprtid = e.dprtid " +
                "left join wss_user AS f on a.designeruid = f.uid " +
                "left join wss_user AS g on  a.checkeruid = g.uid " +
                "left join wss_user AS h on a.revieweruid = h.uid " +
                "left join proc_nc AS i on a.commonncid = i.ncid " +
                "left join wss_user AS j on a.approveruid = j.uid " +
                "left join wss_user AS k  on a.signeruid = k.uid " +
                "left join prod_parts t6 ON a.partsid = t6.partsid " +
                "LEFT JOIN (SELECT ro.op_no,rt.route_step_id, " +
                "   IF( txt.NAME IS NOT NULL AND txt.NAME != '', txt.NAME, wt.NAME ) operationname " +
                "   FROM spp_route_step rt " +
                "   LEFT JOIN spp_route_op ro ON ro.route_op_id = rt.route_op_id " +
                "   LEFT JOIN spp_step_z_op_text txt ON rt.op_text_id = txt.op_text_id " +
                "   LEFT JOIN proc_process_z_worktype wt ON rt.worktype_id = wt.worktype_id " +
                " ) m on a.route_step_id=m.route_step_id " +
                " WHERE a.ncid=" + ncid;
        DataTable dt = DataTableUtil.selectMultiValues(str);
        //ncMapper.selectById(ncid);
        if (dt != null && dt.getRows().size() > 0) {
            Nc nc = new Nc();
            BeanUtil.copyProperties(dt.getRows().get(0), nc);
            return nc;
        }
        return null;
    }

    private String getDatumsUploadtype(String uploadseries) {
        // getDatumsUploadtype(uploadseries4Accessory)
        // TODO 以前是通过STI
        return "pdf";
    }


    @Value("${uploader.ordinary.path:/app/data2/files/}")
    private String uploaderOrdinaryPathDefault;

    @SneakyThrows
    protected static void setBookmarkText(Document doc, String bookmark, String text) {
        doc.getRange().getBookmarks().get(bookmark).setText(text);
    }

    @SneakyThrows
    protected static void setBookmarkText(Document doc, Map<String, Object> marks) {
        BookmarkCollection collection = doc.getRange().getBookmarks();
        for (String mark : marks.keySet()) {
            collection.get(mark).setText(String.valueOf(marks.get(mark)));
        }
    }

    /**
     * 下载程序清单的权限和状态查询
     *
     * @param ncid
     * @return
     */
    public String checkNcDownload(String ncid) {
        Nc nc = baseMapper.selectById(ncid);
        if (nc != null) {
            if (nc.getStatusid() != 2 && nc.getStatusid() != 4) {
                return "只有已入库/通用的数控程序才能进行数控程序清单下载操作";
            }
            //文件下载权限检查：该数控程序的编制、校对、审核和编程组班组长、平台管理员可以直接下载，
            // 其他人需检查该NC程序的签收状态（signin=1），只有已签收的数控程序才能进行下载操作，
            // 否则提示错误“对不起，该数控程序尚未签收无法下载清单！”
            if (ncHelper.checkPower(nc.getNcid().toString(), "manager") ||
                    ncHelper.checkPower(nc.getNcid().toString(), "admin4nc") ||
                    ncHelper.checkPower(nc.getNcid().toString(), "designer") ||
                    ncHelper.checkPower(nc.getNcid().toString(), "checker") ||
                    ncHelper.checkPower(nc.getNcid().toString(), "reviewer")) {
                return "";
            } else if (nc.getSignin() == null || nc.getSignin() != 1) {
                return "对不起，该数控程序尚未签收无法下载清单！";
            }
            return "";
        } else {
            return "该数控程序不存在或者已删除";
        }
    }

    /**
     * 预览程序文件权限和状态查询
     *
     * @param ncid
     * @return
     */
    public String checkNcPreviewFile(String ncid) {
        Nc nc = baseMapper.selectById(ncid);
        if (nc != null) {
            /*if (ncHelper.checkPower(nc.getNcid().toString(), "manager") ||
                    ncHelper.checkPower(nc.getNcid().toString(), "admin4nc")||
                    ncHelper.checkPower(nc.getNcid().toString(), "designer")||
                    ncHelper.checkPower(nc.getNcid().toString(), "checker")||
                    ncHelper.checkPower(nc.getNcid().toString(), "reviewer")) {
                return "";
            }else*/
            if (nc.getSignin() == null || nc.getSignin() != 1) {
                return "对不起，该数控程序尚未签收无法预览文件！";
            }
        }
        return "";
    }


    /**
     * 下载数控程序清单
     */
    public File download(Long ncid, HttpServletResponse response) throws Exception {
        // 清单文件名
        String docname = null;
        // 模板路径：
        String MyDir = fileHandlerService.getTempleteFilePath("plan/list/");
        MyDir = MyDir.replaceFirst("/C:", "")
                .replaceFirst("/D:", "")
                .replaceFirst("/E:", "")
                .replaceFirst("/F:", "");
        //"etech-bpm/etech-plan-cust/src/main/resources/templates/plan/list/";
        // HttpContext.Current.Server.MapPath("~/Ashxs/plan/list/")
        // 工作路径：
        String MyDir0 = fileHandlerService.getEtechFileTempDir();
        //HttpContext.Current.Server.MapPath("~/Ashxs/STI/file_convert/");

        try {
            Nc nc = getNc(ncid);
            /*String msg = checkNcDownload(ncid.toString());
            if (StrUtil.isNotBlank(msg)) {
                throw new BusinessException(msg); //下载验证不通过
            }*/
            //如果是通用程序，则查询原始程序并下载
            if (nc.getStatusid() == 4) {
                nc = getNc(nc.getCommonncid());
            }

            //判断是否需要分栏
            String modelDir = MyDir;
            String str = "SELECT partsnum,partsname FROM proc_nc_commonlist WHERE ncid=" + nc.getNcid() + " AND active=1";
            DataTable commonlistDt = DataTableUtil.selectMultiValues(str);
            if (nc.getSubfield() == 0) {
                if (commonlistDt.Rows.size() <= 20) {
                    modelDir = modelDir + "常规程序清单20190620.docx";
                } else {
                    modelDir = modelDir + "常规程序清单_2页通用零件版20191205.docx";
                }
            } else {
                if (commonlistDt.Rows.size() <= 20) {
                    modelDir = modelDir + "常规程序清单(分栏版)20190620.docx";
                } else {
                    modelDir = modelDir + "常规程序清单_2页通用零件版(分栏版)20191205.docx";
                }
            }
            //获取清单模板
            Document model = new Document(modelDir);
            Document doc = model.deepClone(); //将model克隆过来，然后不进行别的操作了
            DocumentBuilder builder = new DocumentBuilder(doc); //写doc文件的对象
            //获取数控程序修改说明模板
            Document model4Declare = new Document(MyDir + "数控程序修改说明20190620.docx");
            Document doc4Declare = model4Declare.deepClone(); //将model克隆过来，然后不进行别的操作了

            Map<String, Object> bookMarks = new HashMap<>();
            //写入常规信息
            bookMarks.put("pageheader1", nc.getNcnum() + "/" + nc.getVersions());
            bookMarks.put("pageheader2", nc.getPartsnum() + "(" + nc.getPartsname() + ")");
            bookMarks.put("pageheader3", nc.getNcnum() + "/" + nc.getVersions());
            bookMarks.put("pageheader4", nc.getPartsnum() + "(" + nc.getPartsname() + ")");
            bookMarks.put("partsnum", nc.getPartsnum() + (nc.getIsBiaxial() == 1 ? "(主头)" : ""));
            bookMarks.put("partsname", nc.getPartsname());
            bookMarks.put("operationname", (StrUtil.isNotBlank(nc.getOpNo()) ? (nc.getOpNo() + "-") : "") + nc.getOperationname());
            bookMarks.put("workshopname", nc.getWorkshopname());
            bookMarks.put("machinenames", nc.getMachinenames());
            bookMarks.put("designer", nc.getDesigneruname());
            bookMarks.put("checker", nc.getCheckeruname());
            bookMarks.put("reviewer", nc.getRevieweruname());
            bookMarks.put("manager", nc.getApproveruname());
            bookMarks.put("date", DateUtil.format(nc.getFinishdate(), "yyyy-MM-dd"));
            bookMarks.put("pagefooter", DateUtil.format(nc.getFinishdate(), "yyyy-MM-dd"));

            setBookmarkText(doc, bookMarks);
            //写入程序适用零件一览表
            NodeCollection allTables = doc.getChildNodes(NodeType.TABLE, true); //获取word中所有表格table
            Table table = (Table) ((allTables.get(1) instanceof Table) ? allTables.get(1) : null);
            for (int i = 0; i < commonlistDt.Rows.size(); i++) {
                if (i < 20) {
                    editCell(table, doc, i + 1, 0, commonlistDt.getRowStrValue(i, "partsnum"));
                    editCell(table, doc, i + 1, 1, commonlistDt.getRowStrValue(i, "partsname"));
                }
            }
            if (commonlistDt.Rows.size() > 20) {
                Table table0 = (Table) ((allTables.get(2) instanceof Table) ? allTables.get(2) : null);
                for (int i = 20; i < commonlistDt.Rows.size(); i++) {
                    editCell(table0, doc, i - 19, 0, commonlistDt.getRowStrValue(i, "partsnum"));
                    editCell(table0, doc, i - 19, 1, commonlistDt.getRowStrValue(i, "partsname"));
                }
            }

            //获取程序清单、程序文件、附件
            str = "SELECT uploadseries,typeid FROM proc_nc_files WHERE ncid=" + nc.getNcid() + " AND versions='" + nc.getVersions() + "' AND active=1 ORDER BY fileid ASC";
            DataTable uploadseriesDt = DataTableUtil.selectMultiValues(str);

            //插入程序清单
            builder.moveToBookmark("insertList");
            builder.insertBreak(BreakType.PAGE_BREAK);

            for (int i = 0; i < uploadseriesDt.Rows.size(); i++) {
                Integer typeId = Integer.valueOf(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 1 || typeId == 3) {
                    try {
                        String uploadseries4List = uploadseriesDt.getRowStrValue(i, "uploadseries");
                        Document model4List = new Document(etechFileService.getAbsUploadPath(uploadseries4List));
                        Document doc4List = model4List.deepClone();
                        //将程序清单原文件内容插入到"insertList"位置
                        InsertDocument(doc.getRange().getBookmarks().get("insertList").getBookmarkStart().getParentNode(), doc4List);
                        break;

                    } catch (Exception e) {
                        e.printStackTrace();
                        log.warn("插入程序清单出错", e.getMessage());
                        throw new BusinessMessage("插入程序清单出错:" + e.getMessage());
                    }
                }
            }

            builder.moveToBookmark("insertList");
            builder.insertBreak(BreakType.PAGE_BREAK);
            //插入程序文件
            for (int i = uploadseriesDt.Rows.size() - 1; i >= 0; i--) {
                Integer typeId = Integer.valueOf(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 2 || typeId == 4) {
                    String uploadseries4File = uploadseriesDt.getRowStrValue(i, "uploadseries");
                    String filename = etechFileService.getAbsUploadPath(uploadseries4File);

                    try {
                        // 读取文件内容
                        String filedata = FileUtil.readString(filename, getFileEncodeType(filename));

                        builder.moveToBookmark("insertFile");
                        builder.writeln(filedata);
                        builder.insertBreak(BreakType.PAGE_BREAK);

                    } catch (Exception e) {
                        log.error("插入程序文件失败，文件名：" + filename, e.getMessage());
                        throw new BusinessMessage("插入程序文件失败，文件名：" + filename + e.getMessage());
                    }
                }
            }
            builder.moveToBookmark("insertFile");
            builder.insertBreak(BreakType.PAGE_BREAK);

            //插入程序修改说明页
            InsertDocument(doc.getRange().getBookmarks().get("insertDeclare").getBookmarkStart().getParentNode(), doc4Declare);
            setBookmarkText(doc, "partsnum0", nc.getPartsnum());
            setBookmarkText(doc, "machinecode", nc.getMachinenum());

            // 设置清单文件名
            docname = nc.getPartsnum() + "数控程序清单" + (nc.getIsBiaxial() == 1 ? "(主头)" : "") + getCurrentUserEid() + ".pdf";
            // 保存pdf
            doc.save(MyDir0 + docname, SaveFormat.PDF);


            //插入附件
            com.aspose.pdf.Document ncPDF = new com.aspose.pdf.Document(MyDir0 + docname);
            int j = 1;
            for (int i = 0; i < uploadseriesDt.Rows.size(); i++) {
                int typeId = Integer.valueOf(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 7 || typeId == 8) {
                    try {
                        //附件文件名
                        String uploadseries4Accessory = uploadseriesDt.getRowStrValue(i, "uploadseries");
                        String filename = etechFileService.getAbsPreviewPath(uploadseries4Accessory, ContextUtil.getCurrentUserAccount(), true);
                        com.aspose.pdf.Document addPDF = new com.aspose.pdf.Document(FileUtil.getAbsolutePath(filename));
                        // 准备水印
                        String markText = "附件" + j + "：";
                        com.aspose.pdf.TextStamp stamp = new com.aspose.pdf.TextStamp(markText);
                        stamp.setWidth(20);
                        stamp.setHeight(20);
                        for (Page page : addPDF.getPages()) {
                            page.addStamp(stamp);
                        }
                        // 插入附件
                        ncPDF.getPages().add(addPDF.getPages());
                        j = j + 1;
                    } catch (Exception e) {
                        log.error("插入附件出错", e);
                        throw new BusinessMessage("插入附件出错:" + e.getLocalizedMessage());
                    }
                }
            }
            ncPDF.save(MyDir0 + docname);
            //插入水印 工号+日期
            String watermarkText = "工号：" + getCurrentUserEid() + " 时间：" + DateUtil.date();
            AddWaterPrint(MyDir0 + docname, watermarkText);


            File file = new File(MyDir0 + docname);
            //fileHelperService.downloadFile(response, file, docname);
            return file;
        } catch (Exception e2) {
            throw e2;
        } finally {
            if ((new File(MyDir + docname)).isFile()) {
                (new File(MyDir + docname)).delete();
            }
        }
    }

    /**
     * 下载数控程序清单
     */
    public File download4Sub(Long ncid, HttpServletResponse response) throws Exception {
        // 模板路径：
        String MyDir = fileHandlerService.getTempleteFilePath("plan/list/");
        MyDir = MyDir.replaceFirst("/C:", "")
                .replaceFirst("/D:", "")
                .replaceFirst("/E:", "")
                .replaceFirst("/F:", "");
        // 工作路径：
        String MyDir0 = fileHandlerService.getEtechFileTempDir();
        // 设置清单文件名
        String docname = "";
        try {
            Nc nc = getNc(ncid);
            String msg = checkNcDownload(ncid.toString());
            if (StrUtil.isNotBlank(msg)) {
                throw new BusinessException(msg); //下载验证不通过
            }
            //如果是通用程序，则查询原始程序并下载
            if (nc.getStatusid() == 4) {
                nc = getNc(nc.getCommonncid());
            }

            //判断是否需要分栏
            String modelDir = MyDir;
            String str = "SELECT partsnum,partsname FROM proc_nc_commonlist WHERE ncid=" + nc.getNcid() + " AND active=1";
            DataTable commonlistDt = DataTableUtil.selectMultiValues(str);
            if (nc.getSubfield() == 0) {
                if (commonlistDt.Rows.size() <= 20) {
                    modelDir = modelDir + "常规程序清单20190620.docx";
                } else {
                    modelDir = modelDir + "常规程序清单_2页通用零件版20191205.docx";
                }
            } else {
                if (commonlistDt.Rows.size() <= 20) {
                    modelDir = modelDir + "常规程序清单(分栏版)20190620.docx";
                } else {
                    modelDir = modelDir + "常规程序清单_2页通用零件版(分栏版)20191205.docx";
                }
            }
            //获取清单模板
            Document model = new Document(modelDir);
            Document doc = model.deepClone(); //将model克隆过来，然后不进行别的操作了
            DocumentBuilder builder = new DocumentBuilder(doc); //写doc文件的对象
            //获取数控程序修改说明模板
            Document model4Declare = new Document(MyDir + "数控程序修改说明20190620.docx");
            Document doc4Declare = model4Declare.deepClone(); //将model克隆过来，然后不进行别的操作了

            Map<String, Object> bookMarks = new HashMap<>();
            //写入常规信息
            bookMarks.put("pageheader1", nc.getNcnum() + "/" + nc.getVersions());
            bookMarks.put("pageheader2", nc.getPartsnum() + "(" + nc.getPartsname() + ")");
            bookMarks.put("pageheader3", nc.getNcnum() + "/" + nc.getVersions());
            bookMarks.put("pageheader4", nc.getPartsnum() + "(" + nc.getPartsname() + ")");
            bookMarks.put("partsnum", nc.getPartsnum() + "(副头)");
            bookMarks.put("partsname", nc.getPartsname());
            bookMarks.put("operationname", (StrUtil.isNotBlank(nc.getOpNo()) ? (nc.getOpNo() + "-") : "") + nc.getOperationname());
            bookMarks.put("workshopname", nc.getWorkshopname());
            bookMarks.put("machinenames", nc.getMachinenames());
            bookMarks.put("designer", nc.getDesigneruname());
            bookMarks.put("checker", nc.getCheckeruname());
            bookMarks.put("reviewer", nc.getRevieweruname());
            bookMarks.put("manager", nc.getApproveruname());
            bookMarks.put("date", DateUtil.format(nc.getFinishdate(), "yyyy-MM-dd"));
            bookMarks.put("pagefooter", DateUtil.format(nc.getFinishdate(), "yyyy-MM-dd"));

            setBookmarkText(doc, bookMarks);
            //写入程序适用零件一览表
            NodeCollection allTables = doc.getChildNodes(NodeType.TABLE, true); //获取word中所有表格table
            Table table = (Table) ((allTables.get(1) instanceof Table) ? allTables.get(1) : null);
            for (int i = 0; i < commonlistDt.Rows.size(); i++) {
                if (i < 20) {
                    editCell(table, doc, i + 1, 0, commonlistDt.getRowStrValue(i, "partsnum"));
                    editCell(table, doc, i + 1, 1, commonlistDt.getRowStrValue(i, "partsname"));
                }
            }
            if (commonlistDt.Rows.size() > 20) {
                Table table0 = (Table) ((allTables.get(2) instanceof Table) ? allTables.get(2) : null);
                for (int i = 20; i < commonlistDt.Rows.size(); i++) {
                    editCell(table0, doc, i - 19, 0, commonlistDt.getRowStrValue(i, "partsnum"));
                    editCell(table0, doc, i - 19, 1, commonlistDt.getRowStrValue(i, "partsname"));
                }
            }

            //获取程序清单、程序文件、附件
            str = "SELECT uploadseries,typeid FROM proc_nc_files WHERE ncid=" + nc.getNcid() + " AND versions='" + nc.getVersions() + "' AND active=1 ORDER BY fileid ASC";
            DataTable uploadseriesDt = DataTableUtil.selectMultiValues(str);

            //插入程序清单
            builder.moveToBookmark("insertList");
            builder.insertBreak(BreakType.PAGE_BREAK);

            for (int i = 0; i < uploadseriesDt.Rows.size(); i++) {
                //  1,3   副 5
                int typeId = Integer.valueOf(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 5) {
                    try {
                        String uploadseries4List = uploadseriesDt.getRowStrValue(i, "uploadseries");
                        Document model4List = new Document(etechFileService.getAbsUploadPath(uploadseries4List));
                        Document doc4List = model4List.deepClone();
                        //将程序清单原文件内容插入到"insertList"位置
                        InsertDocument(doc.getRange().getBookmarks().get("insertList").getBookmarkStart().getParentNode(), doc4List);
                        break;

                    } catch (Exception e) {
                        log.warn("插入程序清单出错", e.getMessage());
                        throw new BusinessMessage("插入程序清单出错:" + e.getMessage());
                    }
                }
            }

            builder.moveToBookmark("insertList");
            builder.insertBreak(BreakType.PAGE_BREAK);
            //插入程序文件
            for (int i = uploadseriesDt.Rows.size() - 1; i >= 0; i--) {
                Integer typeId = Integer.valueOf(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 6) {
                    String uploadseries4File = uploadseriesDt.getRowStrValue(i, "uploadseries");
                    String filename = etechFileService.getAbsUploadPath(uploadseries4File);
                    try {
                        // 读取文件内容
                        String filedata = FileUtil.readString(filename, getFileEncodeType(filename));

                        builder.moveToBookmark("insertFile");
                        builder.writeln(filedata);
                        builder.insertBreak(BreakType.PAGE_BREAK);

                    } catch (Exception e) {
                        log.error("插入程序文件失败，文件名：" + filename, e.getMessage());
                        throw new BusinessMessage("插入程序文件失败，文件名：" + filename + e.getMessage());
                    }
                }
            }
            builder.moveToBookmark("insertFile");
            builder.insertBreak(BreakType.PAGE_BREAK);

            //插入程序修改说明页
            InsertDocument(doc.getRange().getBookmarks().get("insertDeclare").getBookmarkStart().getParentNode(), doc4Declare);
            setBookmarkText(doc, "partsnum0", nc.getPartsnum());
            setBookmarkText(doc, "machinecode", nc.getMachinenum());

            docname = nc.getPartsnum() + "数控程序清单(副头)" + getCurrentUserEid() + ".pdf";
            // 保存pdf
            doc.save(MyDir0 + docname, SaveFormat.PDF);

            //插入附件
            com.aspose.pdf.Document ncPDF = new com.aspose.pdf.Document(MyDir0 + docname);
            int j = 1;
            for (int i = 0; i < uploadseriesDt.Rows.size(); i++) {
                Integer typeId = Integer.parseInt(uploadseriesDt.getRowStrValue(i, "typeid"));
                if (typeId == 9) {
                    try {
                        //附件文件名
                        String uploadseries4Accessory = uploadseriesDt.getRowStrValue(i, "uploadseries");
                        String filename = etechFileService.getAbsPreviewPath(uploadseries4Accessory, ContextUtil.getCurrentUserAccount(), true);
                        com.aspose.pdf.Document addPDF = new com.aspose.pdf.Document(FileUtil.getAbsolutePath(filename));
                        // 准备水印
                        String markText = "附件" + j + "：";
                        com.aspose.pdf.TextStamp stamp = new com.aspose.pdf.TextStamp(markText);
                        stamp.setWidth(20);
                        stamp.setHeight(20);
                        for (Page page : addPDF.getPages()) {
                            page.addStamp(stamp);
                        }
                        // 插入附件
                        ncPDF.getPages().add(addPDF.getPages());
                        j = j + 1;
                    } catch (Exception e) {
                        log.error("插入附件出错", e);
                        throw new BusinessMessage("插入附件出错:" + e.getLocalizedMessage());
                    }
                }
            }
            ncPDF.save(MyDir0 + docname);
            //插入水印 工号+日期
            String watermarkText = "工号：" + getCurrentUserEid() + " 时间：" + DateUtil.date();
            AddWaterPrint(MyDir0 + docname, watermarkText);


            File file = new File(MyDir0 + docname);
            return file;
            //fileHelperService.downloadFile(response, file, docname);
        } catch (Exception e2) {
            throw e2;
        } finally {
            if ((new File(MyDir + docname)).isFile()) {
                (new File(MyDir + docname)).delete();
            }
        }
    }

    private String getCurrentUserEid() {
        // user.userEid(Integer.parseInt(user.uid()))
        return ContextUtil.getCurrentUserAccount();
    }

    /**
     * 在指定节点之后插入外部文档的内容。
     * 插入文档的分节符和节格式将被忽略。
     */
    private static void InsertDocument(Node insertAfterNode, Document srcDoc) {
        try {
            // Make sure that the node is either a paragraph or table.
            if (insertAfterNode.getNodeType() != NodeType.PARAGRAPH
                    && insertAfterNode.getNodeType() != NodeType.TABLE) {
                throw new IllegalArgumentException("The destination node should be either a paragraph or table.");
            }
            // We will be inserting into the parent of the destination paragraph.
            CompositeNode dstStory = insertAfterNode.getParentNode();
            // This object will be translating styles and lists during the import.
            NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
            // Loop through all sections in the source document.
            for (Section srcSection : srcDoc.getSections()) {
                // Loop through all block level nodes (paragraphs and tables) in the body of the section.
                for (Node srcNode : srcSection.getBody()) {
                    // Let's skip the node if it is a last empty paragraph in a section.
                    if (NodeType.PARAGRAPH == srcNode.getNodeType()) {
                        Paragraph para = (Paragraph) srcNode;
                        if (para.isEndOfSection() && !para.hasChildNodes()) {
                            continue;
                        }
                    }
                    // This creates a clone of the node, suitable for insertion into the destination document.
                    Node newNode = importer.importNode(srcNode, true);
                    // Insert new node after the reference node.
                    dstStory.insertAfter(newNode, insertAfterNode);
                    insertAfterNode = newNode;
                }
            }
        } catch (Exception e) {
            throw e;
        }
    }

    public String getFileEncodeType(String filename) {
        return fileHandlerService.getFileEncodeType(filename);
    }

    /**
     * 修改表中的数据
     *
     * @param table 表名
     * @param doc   文档
     * @param row   要修改行
     * @param cell  要修改列
     * @param value 修改后的值
     */

    public static void editCell(Table table, Document doc, int row, int cell, String value) {
        try {
            Cell c = table.getRows().get(row).getCells().get(cell);
            Paragraph p = new Paragraph(doc);
            p.appendChild(new Run(doc, value));

            p.getParagraphFormat().getStyle().getFont().setSize(10.5);
            //p.ParagraphFormat.Style.Font.Name = "+中文正文";
            c.getFirstParagraph().remove();
            c.appendChild(p);
            table.getRows().get(row).getCells().get(cell).remove();
            table.getRows().get(row).getCells().insert(cell, c);
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 用于文件下载
     */
    public final void downloadFile(String MyDir, String filename) {
        // TODO
//        HttpResponse response = HttpContext.Current.Response;
//        response.ClearHeaders();
//        response.ClearContent();
//        response.Clear();
//        response.Buffer = false;
//        response.AddHeader("content-type", "application/vnd.openxmlformats-officeAspose.Words.Document.wordprocessingml.Aspose.Words.Document");
//        response.AppendHeader("Content-Disposition", "download;filename=" + HttpUtility.UrlEncode(filename, System.Text.Encoding.getUTF8()));
//        response.TransmitFile(MyDir + filename);
//        response.Close();
//        response.End();
    }


    public static void InsertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, HeaderFooterType headerType) {
//        HeaderFooter header = sect.HeadersFooters[headerType];
//        if (header == null)
//        {
//            // There is no header of the specified type in the current section, create it.
//            header = new HeaderFooter(sect.Document, headerType);
//            sect.HeadersFooters.Add(header);
//        }
//        // Insert a clone of the watermark into the header.
//        header.AppendChild(watermarkPara.Clone(true));
    }

    /**
     * 用于PDF文件加水印(下载水印）
     */
    public final void AddWaterPrint(String t_dir_pdf, String watermarkText) {
        //调用公用加用户水印方法
        etechFileService.pdfAddTextStamp(t_dir_pdf, t_dir_pdf, watermarkText, "user");
    }

    /**
     * 获取数控程序详情页数据
     *
     * @param ncplanid
     * @return
     */
    public Map<String, Object> getNcByNcPlanId(String ncplanid) {
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT t1.ncplanid,t1.partsid,t1.partsnum,t1.partsname,t1.mainclassid,");
        sql.append(" t1.processid ,t4.num AS processnum,t4.processname,t1.serial_num as serialNum,");
        sql.append(" t5.plantasknum, t5.plantaskname,t6.manufactureorder,t7.projectname,");
        sql.append(" t1.demanderuid,t1.demanddprtid,t1.workshopid, t6.turningdate, t1.workblankdate,t1.tips");
        sql.append(" from proc_nc_ncplan t1");
        sql.append(" LEFT JOIN proc_process t4 ON t1.processid = t4.processid AND t4.active = 1");
        sql.append(" LEFT JOIN proj_plantask t5 ON t5.plantaskid = t4.plantaskid AND t4.active = 1");
        sql.append(" LEFT JOIN proj_project_order t6 ON t6.projectid = t5.projectid");
        sql.append(" LEFT JOIN proj_project t7 ON t7.projectid = t6.projectid");
        sql.append(" WHERE t1.active = 1 and t1.ncplanid = {}");
        Map<String, Object> map = ncHelper.queryForMap(StrUtil.format(sql, ncplanid));
        if (CollUtil.isNotEmpty(map)) {
            if (StrUtil.isNotBlank(ncplanid)) {
                List<Map<String, Object>> list = jdbcTemplate.queryForList(StrUtil.format("select operationid from proc_nc where ncplanid = {} group by operationid", ncplanid));
                map.put("operationids", list);
            }

        }
        return map;
    }

    /**
     * 程序签收
     *
     * @param id
     */
    public ResultMsg<String> programReceipt(String id) {
        ResultMsg<String> result = new ResultMsg<>();
        result.setOk(false);
        Nc nc = baseMapper.selectById(id);
        if (nc != null) {
            //权限检查：NC平台添加权限、编程技术室班组长、NC平台管理员、PLAN管理员
            //NC程序状态检查：只有入库/通用状态下才能进行该操作
            //已签收的禁止再次签收
            //执行数据更新（signin=1，signeruid为当前用户，signdate为当前时间）
            if (!ncHelper.checkPower(nc.getNcid().toString(), "adder") &&
                    !ncHelper.checkPower(nc.getNcid().toString(), "manager") &&
                    !ncHelper.checkPower(nc.getNcid().toString(), "admin4nc") &&
                    !ncHelper.checkPower(nc.getNcid().toString(), "admin4plan")) {
                result.setMsg("无权限");
            } else if (nc.getStatusid() == 2 || nc.getStatusid() == 4) {
                if (nc.getSignin() == 1) {
                    result.setMsg("已签收的禁止再次签收");
                } else {
                    nc.setSignin(1);
                    nc.setSigneruid(Long.parseLong(ContextUtil.getCurrentUserId()));
                    nc.setSigndate(new Date());
                    baseMapper.updateById(nc);
                    result.setOk(true);
                }
            } else {
                result.setMsg("只有入库/通用状态下才能进行该操作");
            }
        } else {
            result.setMsg("数据不存在或者已删除");
        }
        return result;
    }

    /**
     * 根据文件类型获取nc文件
     *
     * @param types
     * @return
     */
    public Nc getFilesByTypes(String ncid, String types) {
        Nc nc = baseMapper.selectById(ncid);
        if (nc != null) {
            QueryWrapper<NcFiles> wrapper = new QueryWrapper<>();
            wrapper.eq("ncid", ncid).eq("active", 1)
                    .in("typeid", CollUtil.newArrayList(StrUtil.split(types, ",")))
                    .orderByAsc("orderby");
            List<NcFiles> list = ncFileService.list(wrapper);
            if (CollUtil.isNotEmpty(list)) {
                nc.setFiles(list.stream().collect(Collectors.groupingBy(NcFiles::getTypeid)));
            }
        }
        return nc;
    }

    /**
     * 保存数控文件排序
     *
     * @param nc
     */
    public String saveNcFilesOrder(Nc nc) {
        if (nc != null && CollUtil.isNotEmpty(nc.getProc_nc_filesList())) {
            //只有该数控程序计划任务的编制、班组长或者管理员可以进行该操作
            if (!ncHelper.checkPower(nc.getNcid().toString(), "designer") &&
                    !ncHelper.checkPower(nc.getNcid().toString(), "manager")) {
                return "抱歉，只有该数控程序计划任务的编制、班组长或者管理员可以进行该操作！";
            }
            ncFileService.saveOrUpdateBatch(nc.getProc_nc_filesList());
        }
        return null;
    }

    //工序重复性校验
    public boolean checkNcOperations(String ncPlanId, String operationId) {
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        int count = 0;
        try {
            String sql = "select count(1) from proc_nc_operations where active=1 and ncplanid=" + ncPlanId + " and operationid=" + operationId;
            count = jdbcTemplate.queryForObject(sql, int.class);
        } catch (Exception e) {
        }
        return count > 0 ? false : true;
    }

    //工序和机床的复性校验
    public boolean checkNcOperationAndMachine(String ncPlanId, String operationId, String machineId) {
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        int count = 0;
        try {
            String sql = "select count(1) from proc_nc where active=1 and ncplanid=" + ncPlanId + " and operationid=" + operationId + " and machineid=" + machineId;
            count = jdbcTemplate.queryForObject(sql, int.class);
        } catch (Exception e) {
        }
        return count > 0 ? false : true;
    }

    public JSONObject getNcPlan(String ncId) {
        JSONObject jsonObject = null;
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        StringBuffer sqlBuff = new StringBuffer("SELECT ")
                .append("	IF(p.route_step_id > 0,(SELECT IF( txt.NAME IS NOT NULL AND txt.NAME != '', txt.NAME, wt.NAME ) operationname ")
                .append("   FROM spp_route_step rt ")
                .append("   LEFT JOIN spp_route_op ro ON ro.route_op_id = rt.route_op_id ")
                .append("   LEFT JOIN spp_step_z_op_text txt ON rt.op_text_id = txt.op_text_id ")
                .append("   LEFT JOIN proc_process_z_worktype wt ON rt.worktype_id = wt.worktype_id ")
                .append("   where rt.route_step_id = n.route_step_id),p.operationname) operationname,                  ")
                .append("	( SELECT concat( machinecode, ' ', machinename ) FROM proc_nc_z_machine m WHERE m.machineid = n.machineid ) machinename,")
                .append("	p.partsid,p.partsnum,p.partsname,p.componentnum,                                                                                                         ")
                .append("	( SELECT workshopname FROM proc_tooling_z_workshop w WHERE w.workshopid = n.workshopid ) workshopname,                  ")
                .append("	( SELECT mainclassname FROM proc_nc_z_mainclass mc WHERE mc.mainclassid = p.mainclassid ) mainclassname                 ")
                .append("FROM proc_nc n,proc_ncs p WHERE  n.ncplanid = p.ncplanid AND p.active = 1 AND n.ncid = ").append(ncId);
        List<Map<String, Object>> dataList = jdbcTemplate.queryForList(sqlBuff.toString());
        if (dataList != null && !dataList.isEmpty()) {
            jsonObject = new JSONObject(dataList.get(0));
        }
        return jsonObject;
    }

    //通用清单修改零件重复性校验失败
    public boolean checkNcCommonList(String partsnum, String commonlistid) {
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        int count = 0;
        try {
            String sql = "select count(1) from proc_nc_commonlist where active=1 and partsnum = " + partsnum;
            if (StrUtil.isNotBlank(commonlistid)) {
                sql += " and commonlistid <>" + commonlistid;
            }
            count = jdbcTemplate.queryForObject(sql, int.class);
        } catch (Exception e) {
        }
        return count > 0 ? false : true;
    }

    /**
     * 任务取消/恢复
     *
     * @param nc
     * @return
     */
    public String abandon(Nc nc) {
        //编程组班组长、NC平台管理员、PLAN管理员
        if (!ncHelper.checkPower(nc.getNcid().toString(), "manager") &&
                !ncHelper.checkPower(nc.getNcid().toString(), "admin4nc") &&
                !ncHelper.checkPower(nc.getNcid().toString(), "admin4plan")
        ) {
            return "抱歉，只有该数控程序计划任务班组长、NC平台管理员、PLAN管理员可以进行该操作";
        }
        sendAbandonEmail(nc.getNcid(), nc.getAbandontips());
        baseMapper.update(null, Wrappers.<Nc>lambdaUpdate()
                .eq(Nc::getNcid, nc.getNcid())
                .set(Nc::getAbandontips, nc.getAbandontips())
                .set(Nc::getStatusid, nc.getStatusid())
                .set(Nc::getLastdate, new Date())
                .set(Nc::getLastuid, ContextUtil.getCurrentUserId())
        );
        return null;
    }

    /**
     * 用于向编制/校对/需求者发送任务取消提示邮件
     */
    public void sendAbandonEmail(Long ncid, String abandontips) {
        try {
            Nc nc = getNc(ncid);
            if (nc.getStatusid() == 1) {
                DataTable users = new DataTable();
                users.addNewRow("uid", nc.getDesigneruid());
                users.addNewRow("uid", nc.getCheckeruid());
                String name = "【NC数控程序管理平台任务取消提示】 NC编号：" + nc.getNcnum();
                String hrefNcDone = RequestHolder.getUrl() + "/form/formCustSql/view/formCustSqlView.html?code=" + (ncHelper.checkPower(ncid.toString(), "manager") ? "ncDoneForeman" : "ncDone");
                String hrefNcDoneDetail = RequestHolder.getUrl() + "/form/formDef/vueFormDetail.html?key=procNcDetail&ncplanid=" + nc.getNcplanid() + "&listCode=" + (ncHelper.checkPower(ncid.toString(), "manager") ? "procNCDetailNCListForeman" : "procNCDetailNCList");
                String content2 = "&nbsp&nbsp <a href='" + hrefNcDone + "'>点击此处进入NC平台已入库数控程序列表（注意使用谷歌浏览器查看）</a><br><br> " + "&nbsp&nbsp <a href='" + hrefNcDoneDetail + "'>点击此处进入NC平台数控程序详情页面（注意使用谷歌浏览器查看）</a><br><br> " + "&nbsp&nbsp注意：此邮件为平台自动发送，请勿回复！";
                String content = " 您好:<br><br>&nbsp&nbspNC编号: " + nc.getNcnum() + "<br>" + "&nbsp&nbsp零件图号：" + nc.getPartsnum() + "<br>" + "&nbsp&nbsp零件名称: " + nc.getPartsname() + "<br>" + "&nbsp&nbsp加工工序: " + nc.getOperationname() + "<br>" + "&nbsp&nbsp数控程序编制任务已取消，取消原因：" + abandontips + "。<br><br>" + content2;
                (new Mail(users, name, content)).SendEmail();
            }
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 用于检查是否启动编制任务（状态为未开始，同时计划时间和编制不为空）
     */
    public void checkbegin(Long ncid) {
        try {
            Nc ncdata = getNc(ncid);
            if (ncdata == null) {
                throw new BusinessMessage("未查询数控程序，请检查视图数据是否存在");
            }
            if (ncdata.getStatusid() == 0 && ncdata.getPlandate() != null && (ncdata.getDesigneruid() != null && ncdata.getDesigneruid() > 0)) {
                String newncnum = ncHelper.getNextIdByAlias("ncNum"); //生成编号
                String str = "UPDATE proc_nc SET statusid=1,ncnum='" + newncnum + "' WHERE ncid=" + String.valueOf(ncid);
                jdbcTemplate.execute(str);

                //发送任务开始提示邮件
                DataTable users = new DataTable();
                users.addNewRow("uid", ncdata.getDesigneruid());
                if (ncdata.getCheckeruid() != null) {
                    users.addNewRow("uid", ncdata.getCheckeruid());
                }
                String designeruname = etechUserService.getUserNameById(String.valueOf(ncdata.getDesigneruid()));
                String checkeruname = etechUserService.getUserNameById(String.valueOf(ncdata.getCheckeruid()));
                String name = "【NC数控程序管理平台任务开始提示】 NC编号：" + newncnum;
                String content = " 您好:<br><br>&nbsp&nbspNC编号: " + newncnum
                        + "<br>" + "&nbsp&nbsp零件图号：" + ncdata.getPartsnum()
                        + "<br>" + "&nbsp&nbsp零件名称: " + ncdata.getPartsname()
                        + "<br>" + "&nbsp&nbsp加工工序: " + ncdata.getOperationname()
                        + "<br>" + "&nbsp&nbsp加工机床: " + ncdata.getMachinecode() + " " + ncdata.getMachinenames()
                        + "<br>" + "&nbsp&nbsp编制: " + designeruname
                        + "<br>" + "&nbsp&nbsp校对: " + checkeruname
                        + "<br><br>" + "&nbsp&nbsp数控程序编制任务已启动，计划完成日期：" + DateUtil.formatDate(ncdata.getPlandate()) + ",请注意时间节点按时完成。<br><br>"
                        + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formCustSql/view/formCustSqlView.html?code=ncActive'>点击此处进入NC平台个人待办任务页面（注意使用谷歌浏览器查看）</a><br><br> "
                        + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formDef/vueFormDetail.html?key=procNcDetail&ncplanid=" + ncdata.getNcplanid() + "'>点击此处进入NC平台数控程序详情页面（注意使用谷歌浏览器查看）</a><br><br> "
                        + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formCustSql/view/formCustSqlView.html?code=ncplanList'>点击此处进入NC平台计划任务总表（注意使用谷歌浏览器查看）</a><br><br> " + "&nbsp&nbsp注意：此邮件为平台自动发送，请勿回复！";
                (new Mail(users, name, content)).SendEmail();
            }

        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 检查编制&校对是否发生变更，若有且编制任务正在执行，向新的编制校对发送变更提示邮件
     */
    public void checkdesignchange(Nc newdata) {
        try {
            Nc olddata = getNc(newdata.getNcid());
            if (olddata.getStatusid() == 1) {
                String str = "";
                if (!ComparedLongValue(olddata.getDesigneruid(), newdata.getDesigneruid())) {
                    String olddesigneruname = etechUserService.getUserNameById(String.valueOf(olddata.getDesigneruid()));
                    String newdesigneruname = etechUserService.getUserNameById(String.valueOf(newdata.getDesigneruid()));
                    str = str + "&nbsp&nbsp编制由【" + olddesigneruname + "】变为【" + newdesigneruname + "】<br>";
                }
                if (!ComparedLongValue(olddata.getCheckeruid(), newdata.getCheckeruid())) {
                    String oldcheckername = etechUserService.getUserNameById(String.valueOf(olddata.getCheckeruid()));
                    String newcheckername = etechUserService.getUserNameById(String.valueOf(newdata.getCheckeruid()));
                    str = str + "&nbsp&nbsp校对由【" + oldcheckername + "】变为【" + newcheckername + "】<br>";
                }
                if (!str.equals("")) {
                    DataTable users = new DataTable();
                    users.addNewRow("uid", newdata.getDesigneruid());
                    users.addNewRow("uid", newdata.getCheckeruid());
                    String name = "【NC数控程序管理平台任务分配变更提示】 NC编号：" + olddata.getNcnum();
                    String content = " 您好:<br><br>&nbsp&nbspNC编号: " + olddata.getNcnum() + "<br>" + str + "<br>" + "&nbsp&nbsp请注意时间节点按时完成。<br><br>"
                            + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formCustSql/view/formCustSqlView.html?code=ncActive'>点击此处进入NC平台个人待办任务页面（注意使用谷歌浏览器查看）</a><br><br> "
                            + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formDef/vueFormDetail.html?key=procNcDetail&ncplanid=" + olddata.getNcplanid() + "'>点击此处进入NC平台数控程序详情页面（注意使用谷歌浏览器查看）</a><br><br> "
                            + "&nbsp&nbsp <a href='" + RequestHolder.getUrl() + "/form/formCustSql/view/formCustSqlView.html?code=ncplanList'>点击此处进入NC平台计划任务总表（注意使用谷歌浏览器查看）</a><br><br> " + "&nbsp&nbsp注意：此邮件为平台自动发送，请勿回复！";
                    (new Mail(users, name, content)).SendEmail();
                }
            }

        } catch (Exception e) {
            throw e;
        }
    }

    public Long getLongValue(Long value) {
        if (value == null) {
            return 0L;
        }
        return value.longValue();
    }

    public String getStrValue(Object value) {
        if (value == null) {
            return "";
        }
        return String.valueOf(value);
    }

    public boolean ComparedLongValue(Long value1, Long value2) {
        return getLongValue(value1).equals(getLongValue(value2));
    }

    /**
     * 获取机床代号 + 机床名称（俗称）
     */
    public String getMachinencodeAndMachinenames(Long machineid) {
        try {
            String str = "SELECT concat(machinecode,' ',machinename,(CASE WHEN length(machinenvulgo)>0 THEN concat('(',machinenvulgo,')') ELSE '' END)) as machinename FROM proc_nc_z_machine WHERE machineid=" + String.valueOf(machineid);
            str = ncHelper.queryForObject(str, String.class);
            return str;
        } catch (Exception e) {
            throw e;
        }
    }
}
